home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 361_01 / fog.c < prev    next >
C/C++ Source or Header  |  1991-09-18  |  6KB  |  198 lines

  1.  
  2. /* FOG---> A Text Covering Scheme
  3.  *
  4.  * J.Ekwall 29 August 89
  5.  *
  6.  * Copyrighted to the Public Domain.  Unlimited Distribution Autorized.
  7.  *
  8.  * User Assumes All Risks/Liabilities.
  9.  */
  10.  
  11. #include <stdio.h>
  12. #include <ctype.h>
  13. #include <io.h>
  14. #include <time.h>
  15. #include <stdlib.h>
  16. #include <stdek.h>
  17. #include <string.h>
  18.  
  19. /* Declare Constants  */
  20. #define HIBIT3  243
  21.  
  22. /* Declare ProtoTypes */
  23. void Usage(void);
  24.  
  25. char *Documentation[] = {
  26.     "",
  27.     "Usage:",
  28.     "      Fog [options] [file]  --> a Full Ascii Cypher.",
  29.     "",
  30.     "Options:",
  31.     "       /n ---> Use Key n where n is 0-9.",
  32.     "       /D ---> Decode.",
  33.     "       /H ---> An Historical Note.",
  34.     "       /N ---> Neaten up the output w/ Spaces and LineFeeds.",
  35.     "       /S ---> Silent.  Verbose is Default when Redirected.",
  36.     "",
  37.     " --> NOT APPROVED for Classified Information. <---",
  38.     "",
  39.     "Last Update: 17 July 91/EK",
  40.     NULL};
  41.  
  42. char *History[] = {
  43.     "",
  44. "    FOG is based on a KGB trick that totally baffled the CIA in the early",
  45. "60's.  On defecting, the US Station Chief revealed how the KGB had stumpted",
  46. "the experts: Morse Code.",
  47.     "",
  48. "    Morse Code is a Trinary system which, if analyzed using binary",
  49. "techniques, can't be cracked.  The KGB divided the alphabet into three",
  50. "parts, assigning each Trinary bit a random letter drawn from the",
  51. "appropriate group.  This introduces a large \"Noise\" factor.",
  52.     "",
  53. "   FOG uses a similar method except that normal (eight bit) Ascii code",
  54. "is used (6 trinary digits).  Since I had 20 scrambled alphabets handy,",
  55. "I added a touch of Bazeries Cylinders to the show, shifting among them",
  56. "in a round robin.",
  57.     "",
  58. "   The amount of bulk expansion could be as high as 6:1, but generally",
  59. "averages about 3.5:1 because only changed bits are retained and leading",
  60. "zeros are dropped.",
  61.     "",
  62.     NULL };
  63.  
  64. char *Cylinder[] = {
  65.     "ABDMPFHKCEQLWGOXYSINTRUZJV",
  66.     "WXIKSVRYPZJCMNGDFEHLOBQTAU",
  67.     "SPUVIXBHKEDCLMNFGOQTAJWYZR",
  68.     "KVQLYABCDPZIMJNOSWREHXUFGT",
  69.     "HVWFQBACDJRXYZEGLOMNPKSTIU",
  70.     "UVYLFMZACHJNEWGXDKBPIQROST",
  71.     "ALRUXVDYWQZCFKEIGPHNJMSTBO",
  72.     "QTBUVXOHJKPRGSWAYEDILZCNFM",
  73.     "QUBFNEDAJVWXZGOKSMTRYPHILC",
  74.     "GIJCPNEKBDMOQFLRSATUVWXZYH",
  75.     "BLEFGHIJNAKPQXDWYCTMUZORSV",
  76.     "VHRLIFNUDMQTPJBEACSWXYKZOG",
  77.     "LRTCSMKWXIYJBZAPDFNOUVEGQH",
  78.     "QBNRUXYIDZEPSHTFOMVWJCGKAL",
  79.     "UDILMNQSVAPWXRCFTOJYHBEKGZ",
  80.     "JQDRUWXAPGHMSKFVCOYZBTLINE",
  81.     "IUDLXYQFTNZESHKJMPBAORWGVC",
  82.     "YBZXIDFNOGRPAKJMLTEUSVCHQW",
  83.     "IQDPREBTCKONLSUVWXYMZAHFJG",
  84.     "RXYZCLIASPGNUVDJBEKQMTWFOH",
  85.     NULL };
  86.  
  87. /* Declare Globals */
  88. int Decode = 0, NeatFlag = 0, Silent = 0;
  89. char **Disk;
  90. FILE *fp = stdin;
  91.  
  92. /* Declare ProtoTypes */
  93. void DeCode(void);
  94. void EnCode(void);
  95. void Help(char **dp);
  96. void Post(char ch);
  97. void Usage(void);
  98.  
  99. main (int argc, char *argv[])
  100. {
  101.    int c, i, j, N,  Decode = FALSE, Flag, Nybble;
  102.    char *tp1;
  103.  
  104.  /* Check Passed Parameters */
  105.     for (Disk = Cylinder; *argv[1] IS SLASH; argc--, argv++) {
  106.        for (tp1 = argv[1] + 1;(c = toupper(*tp1++)) != NULL; ){
  107.           switch (c) {
  108.           case '0': Disk++;
  109.           case '9': Disk++;
  110.           case '8': Disk++;
  111.           case '7': Disk++;
  112.           case '6': Disk++;
  113.           case '5': Disk++;
  114.           case '4': Disk++;
  115.           case '3': Disk++;
  116.           case '2': Disk++;
  117.           case '1': Disk++;     break;
  118.           case 'D': Decode++;   break;
  119.           case  'H': Help(History);
  120.           case 'N': NeatFlag++; break;
  121.           case 'S': Silent++;   break;
  122.           default: Usage();
  123.           }
  124.        }
  125.     }
  126.  
  127.     /* Check Specified File or Stdin Pipe */
  128.     if ((argc IS 1) && !INFLOW_EXISTS) Usage();
  129.     if (argc IS 2)
  130.        if ((fp = fopen(argv[1], "r")) IS NULL) { perror(argv[1]); exit(3); }
  131.  
  132.  /* Do Business */
  133.     if (!OUTFLOW_EXISTS) Silent++;
  134.     if (!Silent) fprintf(stderr, "\n");
  135.     if (Decode) { NeatFlag = 0; DeCode(); } else EnCode();
  136.     if (!Silent) fprintf(stderr, "\n"); if (NeatFlag) putchar(NL);
  137. }
  138.  
  139. void DeCode(void)
  140. {
  141.     int c, ch = 0, i, Puka = 0;
  142.     char *tp1;
  143.  
  144.     while ((c = fgetc(fp)) != EOF) {
  145.        if (c IS SPACE || c IS NL) continue;
  146.        if ((tp1 = strchr(*Disk, c)) IS NULL) exit(1);
  147.        i = tp1 - (*Disk); ch = ch * 3 + i % 3;
  148.        if (i > 20) {
  149.           Puka  = (ch ^= Puka); Disk++;
  150.           putchar(ch); if (!Silent) fprintf(stderr, "%c", ch); ch = 0;
  151.           if (*Disk IS NULL) Disk = Cylinder;
  152.        }
  153.     }
  154. }
  155.  
  156. void EnCode(void)
  157. {
  158.     int c, ch, i, j, Flag, Puka = 0;
  159.  
  160.     randomize();
  161.     for ( ; (ch = getc(fp)) != EOF; Disk++) {
  162.        if (*Disk IS NULL) Disk = Cylinder;
  163.        c = Puka ^ ch; Puka = ch;
  164.        for (i = HIBIT3, Flag = 0; i > 1; i /= 3) {
  165.           if ((j = c / i) IS 0 && !Flag) continue;
  166.           c %=  i; Flag++; Post((*Disk)[j + 3 * random(7)]);
  167.        }
  168.        Post((*Disk)[c + 21]);
  169.     }
  170. }
  171.  
  172. void Help(char **dp)
  173. {
  174.     for ( ; *dp; dp++) fprintf(stderr,"%s\n", *dp);
  175.     exit(0);
  176. }
  177.  
  178. void Post(char ch)
  179. {
  180.     static int N = 0;
  181.  
  182.     putchar(ch); if (!Silent) putch(ch); if (++N % 5) return;
  183.     if (!Silent)  if (N IS 60) fprintf(stderr, "\n"); else putch(SPACE);
  184.     if (NeatFlag) if (N IS 60) putchar(NL); else putchar(SPACE);
  185.     if (N IS 60) N = 0;
  186. }
  187.  
  188.  
  189. void Usage(void)
  190. {
  191.     char   **dp = Documentation;
  192.  
  193.     for ( ; *dp; dp++) fprintf(stderr,"%s\n", *dp);
  194.     if (OUTFLOW_EXISTS) { rewind(stdout); putchar(DOS_EOF); }
  195.     exit(1);
  196. }
  197.  
  198.